#include "sphere.hpp"

Sphere::Sphere(Material* _material,const Vector& _center = Vector(0.0,0.0,0.0),const double _radius = 0.5) : center(_center) , radius(_radius)
{
	material = _material; /* Material e uma propriedade do Objeto */
}

Sphere::~Sphere(void) { }

Vector Sphere::get_center(void) const { return center; }

double Sphere::get_radius(void) const { return radius; }

Vector Sphere::get_normal(const Vector& point) const { return point.sub_vect(center).normalize(); }

void Sphere::set_center(const Vector& _center) { center = _center; }

void Sphere::set_radius(const double _radius) { radius = _radius; }

double Sphere::intersection(const Ray& _ray,Vector& _point) {
	/* Ax² + Bx + C = 0 */
    
	double delta,distance=90.0;
	//const double a = 1.0;
	const double a = _ray.get_direction().dot_product(_ray.get_direction());
	const double b = 2.0*(_ray.get_direction().dot_product(_ray.get_origin()) - _ray.get_direction().dot_product(center));
	const double c = abs(_ray.get_origin().dot_product(_ray.get_origin()) - 2.0*_ray.get_origin().dot_product(center) + center.dot_product(center)) - radius*radius;
	delta = b*b - 4.0*a*c;
	if (delta >=0.0) {
		double raiz2 = (-b - sqrt(delta))/2.0*a;
		if(raiz2 < 0.0) raiz2 = 90.0;
		else distance = raiz2;
		if(distance >= 0.0 && distance <=5.0) {
			_point.set(
					_ray.get_origin().x + distance*_ray.get_direction().x,
					_ray.get_origin().y + distance*_ray.get_direction().y,
					_ray.get_origin().z + distance*_ray.get_direction().z
				);
			return distance;
		}
	}
	return 90.0;
	
}
